<template>
  <div class="c-scheduler">
    <Holiday :show="show" @close="onClose" :model="model.holiday" :data="holiday"></Holiday>
    <Button class="btn-config" @click="onConfig" type="text">{{ lang.Configure }}</Button>
    <div ref='SchedulerComponent' :style="{height: '100%'}"></div>
  </div>
</template>
 
<script>
/**
 * 对日历组件dhtmlx-scheduler进行二次封装，包含功能：
    绑定模型、支持对事件的CURD、支持配置假期；
 * api文档: https://docs.dhtmlx.com/scheduler/api__refs__scheduler.html
 * */
import { scheduler } from 'dhtmlx-scheduler'
import "public/3thComponents/scheduler/codebase/sources/ext/dhtmlxscheduler_limit"
import Holiday from './holiday.vue'
import dayjs from 'dayjs'

const defaultConfig = {
  skin: 'glossy', // material glossy classic
  header: ['week', 'month', 'date', 'prev', 'today', 'next'],
  limit_time_select: true,
  // date_format:"%Y-%m-%d %H:%i:%s",
}
let localeObj = { 'zh-CN': 'cn', 'en-US': 'en' }

export default {
  name: 'c-scheduler',
  components: { Holiday },
  props: {
    weekend: {      // 配置周末标记
      type: Array,
      default() { return [6, 0] }
    },
    date: {
      default: +new Date(),
    },
    mode: {
      type: String,
      default: 'month',
    },
    config: {
      type: Object,
      default() {
        return {}
      },
    },
    model: {        // 绑定的模型：事件的模型 event、假期的模型 holiday
      type: Object,
      default() {
        return {
          modelName: 'resource',
          event: { type: 'tools', className: 'calendar_event'},
          holiday: { type: 'tools', className: 'calendar_holiday'}
        }
      }
    }
  },
  data() {
    return {
      show: false,
      events: [],
      holiday: [],
      holidayTimes: [],
      apiInstance: this.$modelObject.create(this.model.modelName),
      apiInstanceCollection: this.$modelObject.create(this.model.modelName + 'Collection'),
      apiInstanceHoliday: this.$modelObject.create(this.model.modelName + 'Collection'),
    }
  },
  watch: {
    holiday(val) {
    },
    events(val) {
      scheduler.parse(val)
      scheduler.updateView();
    },
    '$i18n.locale'(val) {
      this.updateLocale();
      scheduler.updateView()
    }
  },
  computed: {
    lang() {
      return {
        'zh-CN': {
          message_ok: "确认",
          message_cancel: "取消",
          icon_save: '保存',
          icon_cancel: '关闭',
          icon_delete: '删除',
          section_description: "描述",
          section_time: "时间范围",
          month_full: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
          Configure: '配置假期',
          holiday: '假期',
          weekend: '周末',
          all: '全部',
          team: '班组',
          teamClass: '班次',
        },
        'en-US': {
          message_ok: "OK",
          message_cancel: "CANCEL",
          icon_save: 'SAVE',
          icon_cancel: 'CANCEL',
          icon_delete: 'DELETE',
          section_description: "Description",
          section_time: "Time period",
          month_full: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
          Configure: 'Configure holiday',
          holiday: 'holiday',
          weekend: 'weekend',
          all: 'all',
          team: 'team',
          teamClass: 'team class',
        }
      }[this.$i18n.locale]
    }
  },
  mounted() {
    this.init()
    this.setTeam()
  },
  methods: {
    init() {
      let curConfig = Object.assign(defaultConfig, this.config)

      this.updateLocale()
      Object.keys(curConfig).forEach(key => {
        scheduler.config[key] = curConfig[key]
      })
      scheduler.locale.labels.section_team = this.lang.team;
      scheduler.locale.labels.section_teamClass = this.lang.teamClass;
      scheduler.xy.lightbox_additional_height = 200
      scheduler.templates.week_date = (start, end) => {
        return dayjs(start).format('YYYY年MM月DD日') + '  -  ' + dayjs(end).format('YYYY年MM月DD日')
      }
      scheduler.templates.month_date = (start) => {
        return dayjs(start).format('YYYY年MM月')
      }
      scheduler.attachEvent("onEventSave",function(id, ev, is_new){
          console.log("file: index.vue:147  scheduler.attachEvent", id, ev, is_new, scheduler.getEvent(id))
          if(ev.start_date > ev.end_date) {
            this.$Message.warging('开始日期不能大于结束日期')
            return false
          }
          return true;
      })

      this.initDataProcessor()
      scheduler.init(
        this.$refs.SchedulerComponent,
        this.date,
        this.mode
      );
      // this.addWeekend()
      this.scheduler = scheduler
      this.query()
      this.queryHolidy()
    },
    initDataProcessor() {
      if (!scheduler.$_dataProcessorInitialized) {
        scheduler.createDataProcessor((entity, action, data, id) => {
          this.$emit(`${entity}-updated`, id, action, data)
          this.onEvent(action, data)
        });
        scheduler.$_dataProcessorInitialized = true
      }
    },
    updateLocale() {
      // 支持国际化
      scheduler.i18n.setLocale(localeObj[this.$i18n.locale])
      scheduler.i18n.setLocale({
        labels: {
          message_ok: this.lang.message_ok,
          message_cancel: this.lang.message_cancel,
          dhx_save_btn: this.lang.icon_save,
          dhx_cancel_btn: this.lang.icon_cancel,
          dhx_delete_btn: this.lang.icon_delete,
          section_description: this.lang.section_description,
          section_time: this.lang.section_time,
        },
        date: {
          month_full: this.lang.month_full,
        }
      })
      scheduler.init_templates()
    },
    query() {
      // 查询事件数据
      this.apiInstanceCollection.query(this.tools.getFilter(this.model.event)).then(flag => {
        if (!flag) {
          return;
        }
        let curRes = [];
        let res = this.apiInstanceCollection.records;
        if (res && res.length) {
          res.forEach(item => {
            item.values.sf_remark && item.values.tf_startDate && (curRes = curRes.concat({
              id: item.id,
              start_date: item.values.tf_startDate,
              end_date: item.values.tf_endDate,
              text: item.values.sf_remark,
              team: item.values.sf_team,           // 班组
              teamClass: item.values.sf_teamClass, // 班次
            }))
          })
          this.events = curRes
        }
      })
    },
    queryHolidy() {
      // 查询假期配置
      this.apiInstanceHoliday.query(this.tools.getFilter(this.model.holiday)).then(flag => {
        if (!flag) {
          return;
        }
        let curRes = [];
        let res = this.apiInstanceHoliday.records;
        if (res && res.length) {
          res.forEach(item => {
            if (item.values.sf_name && item.values.tf_dateRange && item.values.tf_dateRange.length) {
              curRes = curRes.concat({
                id: item.id,
                date: item.values.tf_dateRange,
                name: item.values.sf_name,
                dateObj: item.values.tf_dateRange,
              })
            }
          })
          this.holiday = curRes.sort((pre, cur) => { return cur.date > pre.date ? 1 : -1})
          this.setHoliday()
        }
      })
    },
    onEvent(action, data) {
      switch (action) {
        case "update":
          this.apiInstance.record = {
            ...this.model.event,
            name: data.id,
            id: data.id,
            values: {
              tf_startDate: data.start_date + ':00',
              tf_endDate: data.end_date + ':00',
              sf_remark: data.text,
              sf_team: data.team,
              sf_teamClass: data.teamClass,
            }
          }
          this.apiInstance.updateById()
          break;
        case "delete":
          this.apiInstanceCollection.deleteByIds([data.id])
          break;
        case "create":
        default:
          this.apiInstance.add({
            ...this.model.event,
            name: data.id,
            values: {
              tf_startDate: data.start_date + ':00',
              tf_endDate: data.end_date + ':00',
              sf_remark: data.text,
              sf_team: data.team,
              sf_teamClass: data.teamClass,
            }
          }).then(flag => {
            flag && scheduler.changeEventId(data.id, this.apiInstance.record.id);
          })
          break;
      }
    },
    setHoliday() {
      if (!scheduler) {
        return;
      }
      this.holidayTimes.forEach(id => {
        scheduler.deleteMarkedTimespan(id)
      })
      this.holidayTimes.length = 0
      this.holiday.forEach(item => {
        let start_date = item.dateObj[0] ? (item.dateObj[0] + ' 00:00:00') : ''
        let end_date = item.dateObj[1] ? (item.dateObj[1] + ' 23:59:59') : ''
        var options = {
          start_date: new Date(start_date),
          end_date: new Date(end_date),
          /* creating events on those dates will be disabled - dates are blocked */
          type: item.disabled ? "dhx_time_block" : "",
          zones: "fullday",
          css: "holiday",
          html: item.name || this.lang.holiday
        };
        let id = scheduler.addMarkedTimespan(options);
        this.holidayTimes.push(id)
      })
      scheduler.updateView();
    },
    // 事件弹窗，添加选项：班组、班次
    setTeam() {
      let section = [
        { name:"team", height: 36, type:"select", map_to:"team", default_value: ''},
        { name:"teamClass", height: 36, type:"select", map_to:"teamClass", default_value: ''},
        // defaultSections
        {name:"description", height: 120, map_to:"text", type:"textarea" , focus:true},
        {name:"time", height:72, type:"time", map_to:"auto"}
      ]

      // 获取班组数据
      Promise.all([
        this.$api.StaticLogicInstance.query({condition: "type='staticLogic' and className=='team'"}),
        this.$api.StaticLogicInstance.query({condition: "type='staticLogic' and className=='teamClass'"})
      ]).then(arr => {
        if (arr[0][0]) {
          let options0 = arr[0][0].hier.content.filter(item => item.parentId === 'root').map(item => ({
            key: item.id, label: item.values.name
          }))
          section[0].options = [ {key: '', label: this.lang.all}, ...options0 ]
        }
        if (arr[1][0]) {
          let options1 = arr[1][0].hier.content.filter(item => item.parentId === 'root').map(item => ({
            key: item.id, label: item.values.name
          }))
          section[1].options = [ {key: '', label: this.lang.all}, ...options1 ]
        }

        scheduler.config.lightbox.sections = section
      }).catch(err => {
        console.log("🚀 ~ file: scheduler -> setTeam ~ err:", err)
      })
    },
    addWeekend() {
      if (this.weekend && this.weekend.length) {
        scheduler.addMarkedTimespan({
          days: this.weekend,
          zones: "fullday",
          css: "weekend",
          html: this.lang.weekend
        })
        scheduler.updateView();
      }
    },
    onConfig() {
      this.show = true;
    },
    onClose() {
      this.show = false;
      this.queryHolidy()
    },
  }
};
</script>
 
<style lang="less">
@import '~dhtmlx-scheduler/codebase/dhtmlxscheduler_material.css';
.c-scheduler {
  position: relative;
  width: 100%;
  height: 100%;

  .btn-config {
    position: absolute;
    top: 14px;
    right: 180px;
    z-index: 10;
  }
  &.dhx_scheduler_month .dhx_marked_timespan {
    display: block;
  }

  &.dhx_scheduler_month .dhx_cal_data {
    overflow: hidden;
  }

  .dhx_cal_header {
    box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.1);
  }
  .dhx_cal_data td {
    .dhx_month_head {
      padding: 0 8px;
      font-size: 14px;
    }

    &.dhx_now {
      .dhx_month_head {
        // border-width: 1px 1px 0 1px;
        // border-color: var(--primary-color);
        // border-style: solid;
        background-color: #fff;
        font-weight: 800;
        color: var(--primary-color);
      }
      .dhx_month_body {
        // border-width: 0 1px 1px 1px;
        // border-style: solid;
        // border-color: var(--primary-color);
        background-color: #fff;
      }
    }
  }
  .dhx_scheduler_month .dhx_marked_timespan {
    display: block;
  }
  .dhx_marked_timespan.dhx_now_time {
    border: none;
  }

  .dhx_marked_timespan {
    transform: translate(0, 1px);
    opacity: 0.6;
    text-align: center;

    &.holiday {
      background-color: #fadcd3;
      color: #e9886c;
    }

    &.weekend {
      background-color: #eee;
      color: #666;
    }
  }

  textarea.dhx_cal_editor {
    padding-top: 1px;
  }

  // 覆盖主题颜色
  .dhx_cal_navline.dhx_cal_navline_flex .dhx_cal_tab {
    box-shadow: -1px 0 0 var(--primary-color);
  }

  .dhx_cal_tab {
    // color: var(--primary-color);
    &.active {
      border-color: var(--primary-color);
      background-color: var(--primary-color);
    }
  }

  .dhx_cal_today_button,
  .dhx_cal_event_clear,
  .dhx_btn_set,
  .dhx_cancel_btn_set {
    color: var(--primary-color);
  }

  .dhx_cal_event {
    .dhx_body,
    .dhx_header,
    .dhx_title {
      background: var(--primary-color);
    }
  }
}

.dhx_cal_light {
  .dhx_cancel_btn_set {
    color: var(--primary-color);
  }

  .dhx_cal_ltitle,
  .dhx_save_btn_set {
    border-color: var(--primary-color);
    background: var(--primary-color);
  }
}

.scheduler_modal_box {
  text-align: left;
  z-index: 29999;
  .scheduler_cancel_button div {
    color: var(--primary-color);
  }

  .scheduler_popup_text {
    margin: 20px 30px 28px;
    font-size: 16px;
  }
}</style>